package core

import (
	"bytes"
	"encoding/binary"
	"fmt"
	"math/rand"
	"time"
)

func GetNanoID() uint64 {
	return uint64(time.Now().UnixNano()) //time.Now().UnixMilli()
}

// 生成指定长度的随机字符串,包含大小写字母和数字
func GenerateRandomString(length uint64) (string, error) {
	// 定义字符集，可以根据需要修改
	const charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"

	if length <= 0 {
		return "", fmt.Errorf("length must >0")
	}

	result := make([]byte, length)

	for i := range result {
		// 生成0到charsetLength-1之间的随机数
		randomIndex := rand.Intn(len(charset) - 1)
		result[i] = charset[randomIndex]
	}

	return string(result), nil
}

func WriteUint16(buf *bytes.Buffer, value uint16) ([]byte, error) {
	if err := binary.Write(buf, binary.BigEndian, value); err != nil {
		return nil, err
	}
	return buf.Bytes(), nil
}
func ReadUint16(data []byte) (uint16, error) {
	if len(data) < 2 {
		return 0, fmt.Errorf("data too short to read uint16")
	}
	return binary.BigEndian.Uint16(data[:2]), nil
}

func ReadUint32(data []byte) (uint32, error) {
	if len(data) < 4 {
		return 0, fmt.Errorf("data too short to read uint32")
	}
	return binary.BigEndian.Uint32(data[:4]), nil
}

func WriteUint32(buf *bytes.Buffer, value uint32) ([]byte, error) {
	if err := binary.Write(buf, binary.BigEndian, value); err != nil {
		return nil, err
	}
	return buf.Bytes(), nil
}

func ReadUint64(data []byte) (uint64, error) {
	if len(data) < 8 {
		return 0, fmt.Errorf("data too short to read uint64")
	}
	return binary.BigEndian.Uint64(data[:8]), nil
}

func WriteUint64(buf *bytes.Buffer, value uint64) ([]byte, error) {
	if err := binary.Write(buf, binary.BigEndian, value); err != nil {
		return nil, err
	}
	return buf.Bytes(), nil
}

// 4byte length + data
func ReadString(data []byte) (string, error) {
	if len(data) < 4 {
		return "", fmt.Errorf("data too short to read string")
	}
	length := binary.BigEndian.Uint32(data[:4])
	if len(data) < int(4+length) {
		return "", fmt.Errorf("data too short to read string of length %d", length)
	}
	return string(data[4 : 4+length]), nil
}

// 4byte length + data
func WriteString(buf *bytes.Buffer, str string) ([]byte, error) {
	//data := []byte(str)
	if err := binary.Write(buf, binary.BigEndian, uint32(len(str))); err != nil {
		return nil, err
	}
	if _, err := buf.WriteString(str); err != nil {
		return nil, err
	}
	return buf.Bytes(), nil
}

// 4byte length + []byte
func ReadBytes(data []byte) ([]byte, error) {
	if len(data) < 4 {
		return nil, fmt.Errorf("data too short to read string")
	}
	length := binary.BigEndian.Uint32(data[:4])
	if len(data) < int(4+length) {
		return nil, fmt.Errorf("data too short to read string of length %d", length)
	}
	return data[4 : 4+length], nil
}

// 4byte length + data
func WriteBytes(buffer *bytes.Buffer, data []byte) ([]byte, error) {
	if err := binary.Write(buffer, binary.BigEndian, uint32(len(data))); err != nil {
		return nil, err
	}
	if _, err := buffer.Write(data); err != nil {
		return nil, err
	}
	return buffer.Bytes(), nil
}
